package com.iandun.web.framework.core.web;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.iandun.web.framework.core.exception.GlobalControllerExceptionHandler;
import com.iandun.web.framework.core.http.Response;
import com.iandun.web.framework.core.http.ResponseStatus;
import com.iandun.web.framework.core.validation.ValidationUtils;
import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * 基础控制层
 *
 * @author :jason.liang
 * @date: 2021-05-19 20:50
 */
@Slf4j
public class BaseController {

    /**
     * 无需参数验证情况下的封装
     *
     * @param fun 提供一个函数
     * @return 返回一个 {@link com.iandun.web.framework.core.http.Response}
     */
    public <R> Response<R> action(Supplier<R> fun) {
        return Try.of(() -> {
            R result = fun.get();
            Response<R> response = new Response<>();
            response.setData(result);
            return response;
        }).recover(e -> {
            log.error("An exception occurred during operation->{}", e);
            return (Response<R>) GlobalControllerExceptionHandler.resolveExceptionCustom(e);
        }).get();
    }

    /**
     * 需要参数校验情况下的封装
     *
     * @param fun     提供一个函数
     * @param request 参数验证对象
     * @return 返回一个 {@link com.iandun.web.framework.core.http.Response}
     */
    public <T, R> Response<R> action(T request, Function<T, R> fun) {
        // 验证参数
        return Try.of(() -> {
            // 验证请求参数是否为空
            if (Objects.nonNull(request)) {
                String validateMessage = ValidationUtils.validate(request);
                // 如果不为空代表有参数绑定异常
                if (StringUtils.isNotBlank(validateMessage)) {
                    return new Response<R>(ResponseStatus.BAD_REQUEST.getCode(), "参数格式错误->" + validateMessage);
                }
            }
            // 如果为空代表没有参数绑定异常
            R result = fun.apply(request);
            Response<R> response = new Response<>();
            response.setData(result);
            return response;
        }).recover(e -> {
            // 执行异常情况下
            log.error("An exception occurred during operation->{}", e);
            Response<R> response = GlobalControllerExceptionHandler.resolveExceptionCustom(e);
            return response;
        }).get();
    }
}
